#include "expresultcalframe.h"
#include "ui_expresultcalframe.h"
#include "delegate.h"
#include "algorithm.h"

ExpResultCalFrame::ExpResultCalFrame(QWidget *parent,Experiment* pExperiment) :
    QFrame(parent),
    ui(new Ui::ExpResultCalFrame)
{
    ui->setupUi(this);
    this->pExperiment=pExperiment;

    ComboxDelegate *pComboxDelegate;
    pComboxDelegate=new ComboxDelegate(this,4);
    ui->tableWidget_Element->setItemDelegateForColumn(1,pComboxDelegate);
    pComboxDelegate=new ComboxDelegate(this,4);
    ui->tableWidget_Element->setItemDelegateForColumn(2,pComboxDelegate);
//    pComboxDelegate=new ComboxDelegate(this,5);
//    ui->tableWidget_Element->setItemDelegateForColumn(1,pComboxDelegate);

    CheckBox *pCheckBox;
    pCheckBox=new CheckBox(this,0);
    ui->tableWidget_Check->setItemDelegateForColumn(7,pCheckBox);

    pQwtPlotCal=new MyQwtPlot;
    ui->horizontalLayout_Cal->insertWidget(0,pQwtPlotCal);

    ui->tableWidget_Element->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    connect(ui->tableWidget_Element->selectionModel(),SIGNAL(currentRowChanged(QModelIndex,QModelIndex))
            ,this,SLOT(OnCurrentRowChanged(QModelIndex,QModelIndex)));

    pCurve=NULL;
}

ExpResultCalFrame::~ExpResultCalFrame()
{
    delete ui;
}

void ExpResultCalFrame::LoadData()
{
    disconnect(ui->comboBox_Type,SIGNAL(currentIndexChanged(QString)),
                                        this,SLOT(on_comboBox_Type_currentIndexChanged(QString)));
    ui->comboBox_Type->clear();
    ExpSample expSample=pExperiment->GetExpSample();
    QList<SampleInfor> sampleInfors=expSample.GetSampleInfors();
    QHash<QString,int> samples;
    for(int i=0;i<sampleInfors.count();i++)
    {
        SampleInfor sampleInfor=sampleInfors.at(i);
        if(sampleInfor.sampleType=="全定量标准"||sampleInfor.sampleType=="标准加入标准")//
        {
            samples.insert(sampleInfor.sampleType,i);
        }
    }
    int count=samples.count();
    if(count>0)
    {
        ui->comboBox_Type->addItems(samples.keys());
        on_comboBox_Type_currentIndexChanged(samples.keys().at(0));
    }

    connect(ui->comboBox_Type,SIGNAL(currentIndexChanged(QString)),
                                        this,SLOT(on_comboBox_Type_currentIndexChanged(QString)));
}

void ExpResultCalFrame::on_comboBox_Type_currentIndexChanged(const QString &arg1)
{
    QMap<double,QString> elements;
    if(arg1=="全定量标准")//
    {
        elements=pExperiment->GetQuantitativeElement(2);
    }
    else if(arg1=="标准加入标准")
    {
        elements=pExperiment->GetQuantitativeElement(3);
    }

    ExpMethod* pExpMethod=pExperiment->GetExpMethodPtr();
    int count=elements.count();
    if(count>0)
    {
        disconnect(ui->tableWidget_Element,SIGNAL(itemChanged(QTableWidgetItem*)),
                   this,SLOT(on_tableWidget_Element_itemChanged(QTableWidgetItem*)));
        ui->tableWidget_Element->setRowCount(0);
        int row=0;
        foreach(QString name,elements.values())
        {
            EleMethod eleMethod=pExpMethod->GetEleMethod(name);
            QuantitativePara para=eleMethod.quantitativePara;

            ui->tableWidget_Element->insertRow(ui->tableWidget_Element->rowCount());
            int column=0;
            QTableWidgetItem *pItem;
            pItem=new QTableWidgetItem;
            pItem->setFlags(Qt::NoItemFlags|Qt::ItemIsSelectable|Qt::ItemIsEnabled);
            pItem->setText(name);
            ui->tableWidget_Element->setItem(row,column++,pItem);
            pItem=new QTableWidgetItem;
            pItem->setText(para.functionCount);
            ui->tableWidget_Element->setItem(row,column++,pItem);
            pItem=new QTableWidgetItem;
            pItem->setText(para.weight);
            ui->tableWidget_Element->setItem(row,column++,pItem);
            row++;
        }
        connect(ui->tableWidget_Element,SIGNAL(itemChanged(QTableWidgetItem*)),
                   this,SLOT(on_tableWidget_Element_itemChanged(QTableWidgetItem*)));

        ui->tableWidget_Element->setCurrentIndex(ui->tableWidget_Element->model()->index(0,0));
    }
}

void ExpResultCalFrame::OnCurrentRowChanged(QModelIndex index1,QModelIndex index2)//current index1
{
    if(index1.isValid()==false) return;

    QString name=ui->tableWidget_Element->item(index1.row(),0)->text();
    pExperiment->CalStandardCurve(name);
    UpdateOther(name);
    UpdateTable(name);
    UpdatePlot(name);
}

void ExpResultCalFrame::on_tableWidget_Element_itemChanged(QTableWidgetItem *item)
{
    QString name=ui->tableWidget_Element->item(item->row(),0)->text();
    ExpMethod *pExpMethod=pExperiment->GetExpMethodPtr();
    EleMethod eleMethod=pExpMethod->GetEleMethod(name);

    QString text=ui->tableWidget_Element->item(item->row(),1)->text();
    eleMethod.quantitativePara.functionCount=text;
    text=ui->tableWidget_Element->item(item->row(),2)->text();
    eleMethod.quantitativePara.weight=text;

    pExpMethod->SetMethod(name,eleMethod);
    pExperiment->CalStandardCurve(name);
    UpdateOther(name);
    UpdateTable(name);
    UpdatePlot(name);
}

//cal
bool ExpResultCalFrame::CalFunction(int count)
{
    QList<double> p;
    QList<double> ww;
    QList<double> xx;
    QList<double> yy;

    int dimension = count;	//多项式拟合

    for(int i=0;i<dimension+1;i++)
    {
        p.append(0);
    }
    //	要拟合的数据
    xx<<0.995119<<2.001185<<2.999068<<4.001035<<4.999859<<6.004461<<6.999335
            <<7.999433<<9.002257<<10.003888<<11.004076<<12.001602<<13.003390<<14.001623<<15.003034
            <<16.002561<<17.003010<<18.003897<<19.002563<<20.003530;
    yy<<-7.620000<<-2.460000<<108.760000<<625.020000<<2170.500000<<5814.580000
            <<13191.840000<<26622.060000<<49230.220000<<85066.500000<<139226.280000<<217970.140000<<328843.860000
            <<480798.420000<<684310.000000<<951499.980000<<1296254.940000<<1734346.660000<<2283552.120000<<2963773.500000;
    int sizenum = xx.count();	//	拟合数据的维数
    if(sizenum<count+1) return false;
    Algorithm::PolyFit(ww,xx,yy,p);

    qDebug()<<"拟合系数, 按升序排列如下:";
    for (int i=0;i<dimension+1;i++)				//这里是升序排列，Matlab是降序排列
    {
        qDebug()<<p.at(i);
    }
    return true;
}

void ExpResultCalFrame::UpdateOther(QString name)
{
    ExpMethod* pExpMethod=pExperiment->GetExpMethodPtr();
    EleMethod *pEleMethod =pExpMethod->GetEleMethodPtr(name);
    QuantitativePara* pQuantitativePara=pEleMethod->GetQuantitativeParaPtr();
    QList<double> ratios=pQuantitativePara->GetRatios();
    QString text;
    for(int i=0;i<ratios.count();i++)
    {
        double value=ratios.at(i);
        QString name;
        switch(i)
        {
            case 0:
                name.append(QString::number(value));
                break;
            case 1:
                name.append(QString("%1*CPS").arg(QString::number(value)));
                if(value>0) name.prepend("+");
                break;
            case 2:
                name.append(QString("%1*CPS^2").arg(QString::number(value)));
                if(value>0) name.prepend("+");
                break;
            case 3:
                name.append(QString("%1*CPS^3").arg(QString::number(value)));
                if(value>0) name.prepend("+");
                break;
            case 4:
                name.append(QString("%1*CPS^4").arg(QString::number(value)));
                if(value>0) name.prepend("+");
                break;
        }
        text.append(name);
    }
    text.prepend("Cn=");

    ui->label_Function->setText(text);
}

void ExpResultCalFrame::UpdateTable(QString name)
{
    ExpMethod expMethod=pExperiment->GetExpMethod();
    EleMethod *pEleMethod =expMethod.GetEleMethodPtr(name);
    QuantitativePara* pQuantitativePara=pEleMethod->GetQuantitativeParaPtr();
    QList<QuantitativeParaCal> datas=pQuantitativePara->GetCalDatas();

    ui->tableWidget_Check->setRowCount(0);
    for(int row=0;row<datas.count();row++)
    {
        int column=0;
        double value;
        QuantitativeParaCal data=datas.at(row);
        ui->tableWidget_Check->insertRow(ui->tableWidget_Check->rowCount());
        QTableWidgetItem *pItem;
        pItem=new QTableWidgetItem;
        pItem->setFlags(Qt::NoItemFlags|Qt::ItemIsSelectable|Qt::ItemIsEnabled);//
        pItem->setText(data.sampleName);//
        ui->tableWidget_Check->setItem(row,column++,pItem);
        pItem=new QTableWidgetItem;
        pItem->setFlags(Qt::NoItemFlags|Qt::ItemIsSelectable|Qt::ItemIsEnabled);//
        pItem->setText(QString::number(data.cnRef));//
        ui->tableWidget_Check->setItem(row,column++,pItem);
        pItem=new QTableWidgetItem;
        pItem->setFlags(Qt::NoItemFlags|Qt::ItemIsSelectable|Qt::ItemIsEnabled);//
        value=pQuantitativePara->GetCn(data.cpsMean);
        pItem->setText(QString::number(value));//data.cn
        ui->tableWidget_Check->setItem(row,column++,pItem);
        pItem=new QTableWidgetItem;
        pItem->setFlags(Qt::NoItemFlags|Qt::ItemIsSelectable|Qt::ItemIsEnabled);//
        pItem->setText(QString::number(data.cpsMean));//
        ui->tableWidget_Check->setItem(row,column++,pItem);
        pItem=new QTableWidgetItem;
        pItem->setFlags(Qt::NoItemFlags|Qt::ItemIsSelectable|Qt::ItemIsEnabled);//
        pItem->setText(QString::number(value-data.cnRef));//data.error
        ui->tableWidget_Check->setItem(row,column++,pItem);
        pItem=new QTableWidgetItem;
        pItem->setFlags(Qt::NoItemFlags|Qt::ItemIsSelectable|Qt::ItemIsEnabled);//
        pItem->setText(QString::number((data.cnRef==0)?0:(value-data.cnRef)/data.cnRef));//data.rError
        ui->tableWidget_Check->setItem(row,column++,pItem);
        pItem=new QTableWidgetItem;
        pItem->setFlags(Qt::NoItemFlags|Qt::ItemIsSelectable|Qt::ItemIsEnabled);//
        QString text;
        for(int i=0;i<data.cpss.count();i++)
        {
            text.append(" "+QString::number(data.cpss.at(i)));
        }
        pItem->setText(text);//
        ui->tableWidget_Check->setItem(row,column++,pItem);
        pItem=new QTableWidgetItem;
        pItem->setFlags(Qt::NoItemFlags|Qt::ItemIsSelectable|Qt::ItemIsEnabled);//
        pItem->setText(QString::number(data.bIsUsed));//
        ui->tableWidget_Check->setItem(row,column++,pItem);
    }
}
void ExpResultCalFrame::UpdatePlot(QString name)
{
    if(pCurve!=NULL) delete pCurve;
    foreach(QwtPlotMarker *pMarker,pMarkers)
    {
        delete pMarker;
    }
    pMarkers.clear();

    ExpMethod expMethod=pExperiment->GetExpMethod();
    EleMethod *pEleMethod =expMethod.GetEleMethodPtr(name);
    QuantitativePara* pQuantitativePara=pEleMethod->GetQuantitativeParaPtr();
    QList<QuantitativeParaCal> datas=pQuantitativePara->GetCalDatas();

    pCurve = new QwtPlotCurve;
    pCurve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
    pCurve->setPen(Qt::red);
    pCurve->attach(pQwtPlotCal);
    pCurve->setVisible(true);
    Algorithm::SetRatios(pQuantitativePara->GetRatios());
    FunctionData *pFunctionData=new FunctionData(Algorithm::Func);
    pCurve->setData(pFunctionData);

    for(int i=0;i<datas.count();i++)
    {
        QuantitativeParaCal data=datas.at(i);
        QwtPlotMarker *pMarker = new QwtPlotMarker();
        QwtSymbol *symbol=new QwtSymbol;
        symbol->setColor(Qt::blue);
        symbol->setStyle(QwtSymbol::Rect);
        symbol->setSize(5,5);
        pMarker->setSymbol(symbol);
        pMarker->setValue(QPointF(data.cpsMean,data.cnRef));
        pMarker->setVisible(true);
        pMarker->attach(pQwtPlotCal);
        pMarkers.append(pMarker);
    }

    pQwtPlotCal->setTitle("校准曲线");
    pQwtPlotCal->setAxisTitle(QwtPlot::xBottom,"响应值（cps）");
    pQwtPlotCal->setAxisTitle(QwtPlot::yLeft,"浓度");
    pQwtPlotCal->setAxisScale(QwtPlot::xBottom,0,1000);
    pQwtPlotCal->setAxisScale(QwtPlot::yLeft,0,1000);
    pQwtPlotCal->replot();
}



